package com.caocaog.market.pay.syb.utils;

import com.caocaog.market.pay.syb.config.SybConfig;
import com.caocaog.market.pay.syb.dto.SybDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;

@Slf4j
@Component
public class SybPay {

    @Value(value = "${syb.notify_url}")
    private String notify_url;

    @Value(value = "${syb.wxAppId}")
    private String wxAppId;

    public Map<String, String> pay(SybDto sybDto, String notifyMethod) throws Exception {

        HttpConnectionUtil http = httpInit(SybConfig.SYB_APIURL + "/pay");
        TreeMap<String, String> params = new TreeMap<String, String>();
        params.put("sub_appid", wxAppId);
        params.put("acct", sybDto.getAcct());
        if (!SybUtil.isEmpty(SybConfig.SYB_ORGID)) {
            params.put("orgid", SybConfig.SYB_ORGID);
        }
//            params.put("cusid", SybConfig.SYB_CUSID);
//            params.put("appid", SybConfig.SYB_APPID);
        params.put("cusid", sybDto.getCusid());
        params.put("appid", sybDto.getAppid());
        params.put("version", "11");
        params.put("trxamt", String.valueOf(sybDto.getPayMoney().multiply(new BigDecimal("100")).longValue()));
//            params.put("trxamt", "10");
        params.put("reqsn", sybDto.getReqSn());
        params.put("paytype", sybDto.getPayType());
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("body", sybDto.getBody());
        params.put("notify_url", notify_url + notifyMethod);
        params.put("signtype", SybConfig.SIGN_TYPE);

        //签名方式
        params.put("sign", SybUtil.unionSign(params, SybConfig.SYB_RSACUSPRIKEY, SybConfig.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, StandardCharsets.UTF_8);
        Map<String, String> map = handleResult(result);
        return map;
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public static Map<String, String> handleResult(String result) throws Exception {
        Map map = SybUtil.json2Obj(result, Map.class);
        if (map == null) {
            throw new Exception("返回数据错误");
        }
        if ("SUCCESS".equals(map.get("retcode"))) {
            TreeMap tmap = new TreeMap(map);
            if (SybUtil.validSign(tmap, SybConfig.SYB_RSATLPUBKEY, SybConfig.SIGN_TYPE)) {
                System.out.println("签名成功");
                return map;
            } else {
                throw new Exception("验证签名失败");
            }

        } else {
            throw new Exception(map.get("retmsg").toString());
        }
    }


    public Map<String, String> refund(SybDto sybDto) throws Exception {
        HttpConnectionUtil http = httpInit(SybConfig.SYB_APIURL + "/refund");
        TreeMap<String, String> params = new TreeMap<String, String>();
        if (!SybUtil.isEmpty(SybConfig.SYB_ORGID))
            params.put("orgid", SybConfig.SYB_ORGID);
        params.put("cusid", SybConfig.SYB_CUSID);
        params.put("appid", SybConfig.SYB_APPID);
        params.put("version", "11");
        params.put("trxamt", String.valueOf(sybDto.getTrxAmt()));
        params.put("reqsn", sybDto.getReqSn());
        params.put("oldreqsn", sybDto.getOldReqSn());
        params.put("oldtrxid", sybDto.getOldTrxId());
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("signtype", SybConfig.SIGN_TYPE);
        params.put("remark", sybDto.getRemark());

        params.put("sign", SybUtil.unionSign(params, SybConfig.SYB_RSACUSPRIKEY, SybConfig.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, StandardCharsets.UTF_8);
        return handleResult(result);
    }

    public Map<String, String> close(SybDto sybDto) throws Exception {
        HttpConnectionUtil http = httpInit(SybConfig.SYB_APIURL + "/close");
        TreeMap<String, String> params = new TreeMap<String, String>();
        if (!SybUtil.isEmpty(SybConfig.SYB_ORGID))
            params.put("orgid", SybConfig.SYB_ORGID);
        params.put("cusid", SybConfig.SYB_CUSID);
        params.put("appid", SybConfig.SYB_APPID);
        params.put("version", "12");
        if (StringUtils.isBlank(sybDto.getOldTrxId())) {
            params.put("oldreqsn", sybDto.getOldReqSn());
        } else {
            params.put("oldtrxid", sybDto.getOldTrxId());
        }
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("signtype", SybConfig.SIGN_TYPE);

        params.put("sign", SybUtil.unionSign(params, SybConfig.SYB_RSACUSPRIKEY, SybConfig.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, StandardCharsets.UTF_8);
        Map<String, String> map = handleResult(result);
        log.info("订单关闭返回结果:{}", map);
        return map;
    }

    public Map<String, String> query(SybDto sybDto) throws Exception {
        HttpConnectionUtil http = httpInit(SybConfig.SYB_APIURL + "/query");
        TreeMap<String, String> params = new TreeMap<String, String>();
        if (!SybUtil.isEmpty(SybConfig.SYB_ORGID))
            params.put("orgid", SybConfig.SYB_ORGID);
        params.put("cusid", SybConfig.SYB_CUSID);
        params.put("appid", SybConfig.SYB_APPID);
        params.put("version", "11");
        if (StringUtils.isBlank(sybDto.getTrxId())) {
            params.put("reqsn", sybDto.getReqSn());
        } else {
            params.put("trxid", sybDto.getTrxId());
        }
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("signtype", SybConfig.SIGN_TYPE);

        params.put("sign", SybUtil.unionSign(params, SybConfig.SYB_RSACUSPRIKEY, SybConfig.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, StandardCharsets.UTF_8);
        return handleResult(result);
    }

    public Map<String, String> cancel(SybDto sybDto) throws Exception {
        HttpConnectionUtil http = httpInit(SybConfig.SYB_APIURL + "/cancel");
        TreeMap<String, String> params = new TreeMap<String, String>();
        if (!SybUtil.isEmpty(SybConfig.SYB_ORGID))
            params.put("orgid", SybConfig.SYB_ORGID);
        params.put("cusid", SybConfig.SYB_CUSID);
        params.put("appid", SybConfig.SYB_APPID);
        params.put("version", "11");
        params.put("trxamt", String.valueOf(sybDto.getTrxAmt()));
        params.put("reqsn", sybDto.getReqSn());
        params.put("oldtrxid", sybDto.getOldTrxId());
        params.put("oldreqsn", sybDto.getOldReqSn());
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("signtype", SybConfig.SIGN_TYPE);
        String appkey = "";
        if (SybConfig.SIGN_TYPE.equals("RSA")) {
            appkey = SybConfig.SYB_RSACUSPRIKEY;
        } else if (SybConfig.SIGN_TYPE.equals("SM2")) {
            appkey = SybConfig.SYB_SM2PPRIVATEKEY;
        } else {
            appkey = SybConfig.SYB_MD5_APPKEY;
        }
        params.put("sign", SybUtil.unionSign(params, appkey, SybConfig.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, StandardCharsets.UTF_8);
        return handleResult(result);
    }

    public Map<String, String> scanPay(SybDto sybDto) throws Exception {
        // TODO Auto-generated method stub
        HttpConnectionUtil http = httpInit(SybConfig.SYB_APIURL + "/scanqrpay");

        TreeMap<String, String> params = new TreeMap<String, String>();
        if (!SybUtil.isEmpty(SybConfig.SYB_ORGID))
            params.put("orgid", SybConfig.SYB_ORGID);
        params.put("cusid", SybConfig.SYB_CUSID);
        params.put("appid", SybConfig.SYB_APPID);
        params.put("version", "11");
        params.put("trxamt", String.valueOf(sybDto.getTrxAmt()));
        params.put("reqsn", sybDto.getReqSn());
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("body", sybDto.getBody());
        params.put("remark", sybDto.getRemark());
        params.put("authcode", sybDto.getAuthCode());
        params.put("limit_pay", sybDto.getLimitPay());
        params.put("asinfo", sybDto.getAsInfo());
        params.put("signtype", SybConfig.SIGN_TYPE);
        params.put("terminfo", sybDto.getTermInfo());
        params.put("fqnum", sybDto.getFqNum());
        String appkey = "";
        if (SybConfig.SIGN_TYPE.equals("RSA")) {
            appkey = SybConfig.SYB_RSACUSPRIKEY;
        } else if (SybConfig.SIGN_TYPE.equals("SM2")) {
            appkey = SybConfig.SYB_SM2PPRIVATEKEY;
        } else {
            appkey = SybConfig.SYB_MD5_APPKEY;
        }
        params.put("sign", SybUtil.unionSign(params, appkey, SybConfig.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, StandardCharsets.UTF_8);
        return handleResult(result);
    }

    private HttpConnectionUtil httpInit(String connectUrl) throws Exception {
        HttpConnectionUtil http = new HttpConnectionUtil(connectUrl);
        http.init();
        return http;

    }
}
